home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
PC World 2007 June
/
PCWorld_2007-06_cd.bin
/
v cisle
/
tclock
/
tclocklight-040702-3.exe
/
source
/
exe
/
menu.c
< prev
next >
Wrap
C/C++ Source or Header
|
2004-09-07
|
8KB
|
311 lines
/*-------------------------------------------------------------
menu.c : context menu of TClock
(C) 1997-2003 Kazuto Sato
Please read readme.txt about the license.
Written by Kazubon, Nanashi-san
---------------------------------------------------------------*/
#include "tclock.h"
#include "../common/command.h"
/* Globals */
void ContextMenuCommand(HWND hwnd, int id);
void EndMenu(void);
void OnContextMenu(HWND hwnd, HWND hwndClicked, int xPos, int yPos);
void OnExitMenuLoop(HWND hwnd);
void SetFocusTClockMain(HWND hwnd);
/* Statics */
typedef struct _tagMenuStruct
{
int id;
char command[MAX_PATH];
} MENUSTRUCT;
typedef MENUSTRUCT* PMENUSTRUCT;
static void SendOnContextMenu(void);
static void CheckMenu(HMENU hmenu);
static void LoadMenuFromText(HMENU hmenu,
const char *fname, const WIN32_FIND_DATA *pfd);
static int ReadMenuCommands(HMENU hmenu, const char *p,
PMENUSTRUCT pmenus);
static HMENU m_hMenu = NULL;
static char m_tcmenutxt[MAX_PATH] = { 0 };
static PMENUSTRUCT m_pmenuCommands = NULL;
static int m_numCommands = 0;
static DWORD m_lasttime = 0;
/*------------------------------------------------
open/execute a file with context menu
--------------------------------------------------*/
void ContextMenuCommand(HWND hwnd, int id)
{
int i;
if(!m_pmenuCommands) return;
for(i = 0; i < m_numCommands; i++)
{
if(id == m_pmenuCommands[i].id)
{
if(m_pmenuCommands[i].command[0])
ExecCommandString(hwnd, m_pmenuCommands[i].command);
break;
}
}
}
/*------------------------------------------------
clean up
--------------------------------------------------*/
void EndMenu(void)
{
if(m_hMenu) DestroyMenu(m_hMenu);
m_hMenu = NULL;
if(m_pmenuCommands) free(m_pmenuCommands);
m_pmenuCommands = NULL;
}
/*------------------------------------------------
when the clock is right-clicked
show pop-up menu
--------------------------------------------------*/
void OnContextMenu(HWND hwnd, HWND hwndClicked, int xPos, int yPos)
{
WIN32_FIND_DATA fd;
HANDLE hfind;
SendOnContextMenu();
if(m_tcmenutxt[0] == 0 || !IsFile(m_tcmenutxt))
{
// common/tclang.c
FindFileWithLangCode(m_tcmenutxt, GetUserDefaultLangID(), TCMENUTXT);
}
hfind = FindFirstFile(m_tcmenutxt, &fd);
if(hfind != INVALID_HANDLE_VALUE)
{
FindClose(hfind);
if(m_lasttime != fd.ftLastWriteTime.dwLowDateTime)
{
EndMenu();
m_lasttime = fd.ftLastWriteTime.dwLowDateTime;
}
}
else m_lasttime = 0;
// create popup menu and append items from tcmenu.txt
if(!m_hMenu)
{
m_hMenu = CreatePopupMenu();
if(hfind != INVALID_HANDLE_VALUE)
LoadMenuFromText(m_hMenu, m_tcmenutxt, &fd);
else
LoadMenuFromText(m_hMenu, NULL, NULL);
}
CheckMenu(m_hMenu);
// get keyboard input
SetFocusTClockMain(hwnd);
// open popup menu
TrackPopupMenu(m_hMenu, TPM_LEFTALIGN|TPM_RIGHTBUTTON,
xPos, yPos, 0, hwnd, NULL);
}
/*------------------------------------------------
WM_EXITMENULOOP message
--------------------------------------------------*/
void OnExitMenuLoop(HWND hwnd)
{
HWND hwndBar;
DWORD pid, clockthread, mythread;
hwndBar = GetTaskbarWindow();
if(hwndBar)
{
clockthread = GetWindowThreadProcessId(hwndBar, &pid);
mythread = GetCurrentThreadId();
AttachThreadInput(clockthread, mythread, TRUE);
SetFocus(hwndBar);
AttachThreadInput(clockthread, mythread, FALSE);
}
}
/*------------------------------------------------
set keyboard focus to the main window forcely
--------------------------------------------------*/
void SetFocusTClockMain(HWND hwnd)
{
DWORD pid, curthread, mythread;
curthread = GetWindowThreadProcessId(GetForegroundWindow(), &pid);
mythread = GetCurrentThreadId();
AttachThreadInput(mythread, curthread, TRUE);
SetFocus(hwnd);
AttachThreadInput(mythread, curthread, FALSE);
}
/*------------------------------------------------
tell other programs
that right-click menu is to open
--------------------------------------------------*/
void SendOnContextMenu(void)
{
HWND hwndProg;
char entry[20], buf[100], cname[80], num[20];
int i, msg;
for(i = 0; ; i++)
{
wsprintf(entry, "App%d", i + 1);
GetMyRegStr("OnContextMenu", entry, buf, 100, "");
if(!buf[0]) break;
parse(cname, buf, 0, 80);
if(!cname[0]) continue;
parse(num, buf, 1, 20);
if(!num[0]) continue;
msg = atoi(num);
hwndProg = FindWindow(cname, NULL);
if(hwndProg)
SendMessage(hwndProg, msg, 0, 0);
}
}
/*------------------------------------------------
enable/disable menu item
--------------------------------------------------*/
void CheckMenu(HMENU hmenu)
{
char s[80];
int winver = CheckWinVersion();
EnableMenuItem(hmenu, IDC_TASKMAN, MF_BYCOMMAND|
((winver&WINNT) ? MF_ENABLED:MF_GRAYED) );
EnableMenuItem(hmenu, IDC_SYNCTIME, MF_BYCOMMAND|
(GetMyRegStr("SNTP", "Server", s, 80, "") > 0 ?
MF_ENABLED:MF_GRAYED));
}
/*------------------------------------------------
read menu commands from tcmenu*.txt
--------------------------------------------------*/
void LoadMenuFromText(HMENU hmenu,
const char *fname, const WIN32_FIND_DATA *pfd)
{
HFILE hf = HFILE_ERROR;
int size;
char *pbuf;
if(fname && pfd)
hf = _lopen(fname, OF_READ);
if(hf == HFILE_ERROR)
{
AppendMenu(hmenu, MF_STRING, IDC_EXIT, "Exit TClock");
return;
}
size = (int)pfd->nFileSizeLow;
pbuf = malloc(size + 1);
_lread(hf, pbuf, size);
pbuf[size] = 0;
_lclose(hf);
m_numCommands = ReadMenuCommands(NULL, pbuf, NULL);
if(m_pmenuCommands) free(m_pmenuCommands);
m_pmenuCommands = NULL;
if(m_numCommands > 0)
m_pmenuCommands = malloc(sizeof(MENUSTRUCT) * m_numCommands);
ReadMenuCommands(hmenu, pbuf, m_pmenuCommands);
free(pbuf);
}
/*------------------------------------------------
add commands to MENUSTRUCT and HMENU
--------------------------------------------------*/
int ReadMenuCommands(HMENU hmenu, const char *p,
MENUSTRUCT* pmenus)
{
int count = 0;
int idCommand = 1;
char name[81], command[MAX_PATH];
while(*p)
{
if(*p == '#' ||
*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n')
{
p = nextline(p);
}
else if(*p == '-' && *(p + 1) == '-')
{
if(hmenu)
AppendMenu(hmenu, MF_SEPARATOR, 0, 0);
p = nextline(p);
}
else
{
BOOL bdigit;
int id, i;
char quot;
quot = 0;
if(*p == '\"' || *p == '\'') { quot = *p; p++; }
for(i = 0; i < 80 &&
*p && *p != '\r' && *p != '\n'; i++)
{
if(quot) { if(*p == quot) { p++; break; } }
else if(*p == ' ' || *p == '\t') break;
name[i] = *p++;
}
name[i] = 0;
while(*p == ' ' || *p == '\t') p++;
quot = 0;
if(*p == '\"' || *p == '\'') { quot = *p; p++; }
for(i = 0; i < MAX_PATH-1 &&
*p && *p != '\r' && *p != '\n'; i++)
{
if(quot && *p == quot) break;
command[i] = *p++;
}
command[i] = 0;
bdigit = isdigitstr(command);
if(bdigit) id = atoi(command);
else id = idCommand;
if(hmenu)
AppendMenu(hmenu, MF_STRING, id, name);
if(!bdigit)
{
if(pmenus)
{
pmenus[count].id = id;
strcpy(pmenus[count].command, command);
}
count++;
if(count >= 50) return count;
idCommand++;
}
p = nextline(p);
}
}
return count;
}